package feign.hystrix;

import feign.Util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 桥接 sentinel 和 openfeign,
 * 仍然可以使用 @FeignClient(value = "sentinel-openfeign-payment", fallback = PaymentServiceFallback.class)
 * 但是 hystrix 换成了 sentinel
 *
 * 实现 feign.hystrix.FallbackFactory
 * org.springframework.cloud.openfeign.FallbackFactory
 * 解决 feign.sentinel.enabled: true, 找不到 feign.hystrix.FallbackFactory 问题
 *
 * @author hzy
 * @since 2022/3/5 23:48
 */
public interface FallbackFactory<T> {
    T create(Throwable cause);

    public static final class Default<T> implements FallbackFactory<T> {
        final Log logger;
        final T constant;

        public Default(T constant) {
            this(constant, LogFactory.getLog(org.springframework.cloud.openfeign.FallbackFactory.Default.class));
        }

        Default(T constant, Log logger) {
            this.constant = Util.checkNotNull(constant, "fallback", new Object[0]);
            this.logger = (Log)Util.checkNotNull(logger, "logger", new Object[0]);
        }

        public T create(Throwable cause) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("fallback due to: " + cause.getMessage(), cause);
            }

            return this.constant;
        }

        public String toString() {
            return this.constant.toString();
        }
    }
}

